﻿/*********************************************************
** File Name:	SendMailService.cs
** Copyright (C) 2010 hiSoft ITDC. All right reserved.
** Creator:	xubaojun
** Create date:	2010-05-13
** Modifier:	
** Modify date:	
** Description:	发送邮件服务
*********************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using System.Net.Mime;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text.RegularExpressions;
using Common;
using Base;

namespace Job.SendMail
{
    public class SendMailService : IServiceStrategy
    {
        #region  变量
        private static readonly log4net.ILog _log = log4net.LogManager.GetLogger("Job.SendMail.Logging");
        string areaName = System.Configuration.ConfigurationSettings.AppSettings["AreaName"];
        string password = System.Configuration.ConfigurationSettings.AppSettings["pwd"];
        string serverName = System.Configuration.ConfigurationSettings.AppSettings["serverName"];
        string fromMail = System.Configuration.ConfigurationSettings.AppSettings["MailFrom"];
        string debugMailAddress = System.Configuration.ConfigurationSettings.AppSettings["DebugMailAddress"];
        string fromName = System.Configuration.ConfigurationSettings.AppSettings["MailFromName"];
        #endregion

        #region 邮件发送

        /// <summary>
        /// 发送需要发送的邮件
        /// </summary>
        public void SendMail()
        {
            _log.Info("----------------------------Begin--------------------------------");
            _log.Info("发送邮件开始");

            try
            {
                DataTable dt = new DataTable();
                string[] sendto = null;
                string[] sendcc = null;
                string sqlstr = "select * from dbo.COM_SendMail where is_send='N' and retry_times < 5";

                DataProvider sql = DataProvider.Instance("AccountManageSystem");
                dt = sql.ExecuteDataset(sqlstr).Tables[0];
                SmtpClient client = new SmtpClient();
                MailMessage message = new MailMessage();
                client.Credentials = new NetworkCredential(@areaName, @password);
                client.Host = serverName;
                message.From = new MailAddress(@fromMail, fromName);

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    message.Subject = dt.Rows[i]["subject"].ToString();

                    if (debugMailAddress.Trim() != "")
                    {
                        message.To.Add(debugMailAddress);
                    }
                    else
                    {
                        Regex reg = new Regex(@"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$");
                        sendto = dt.Rows[i]["mail_to"].ToString().Split(';');
                        for (int j = 0; j < sendto.Length; j++)
                        {
                            string oneTo = sendto[j].Trim();
                            if (!string.IsNullOrEmpty(oneTo) && reg.IsMatch(oneTo))
                            {
                                message.To.Add(oneTo);
                            }
                        }

                        sendcc = dt.Rows[i]["mail_cc"].ToString().Split(';');
                        for (int k = 0; k < sendcc.Length; k++)
                        {
                            string oneCc = sendcc[k].Trim();
                            if (!string.IsNullOrEmpty(oneCc) && reg.IsMatch(oneCc))
                            {
                                message.CC.Add(oneCc);
                            }
                        }
                    }

                    string priority = dt.Rows[i]["status"].ToString();

                    if (string.IsNullOrEmpty(priority) || priority == "2")
                    {
                        message.Priority = MailPriority.Normal;
                    }
                    if (priority == "3")
                    {
                        message.Priority = MailPriority.High;
                    }
                    if (priority == "1")
                    {
                        message.Priority = MailPriority.Low;
                    }

                    ///添加附件。
                    string[] file = dt.Rows[i]["attachment_file"].ToString().Split(';');
                    int count = (int)file.Length;
                    string[] filepath = new string[count];
                    for (int n = 0; n < file.Length; n++)
                    {
                        if (file[n] != "")
                        {
                            //filepath[n] = @"C:\\mailfile\\" + file[n];
                            filepath[n] = file[n];
                            if (System.IO.File.Exists(filepath[n]) == true)
                            {
                                //附件对象
                                Attachment data = new Attachment(filepath[n], MediaTypeNames.Application.Octet);
                                //附件资料
                                ContentDisposition disposition = data.ContentDisposition;
                                disposition.CreationDate = System.IO.File.GetCreationTime(file[n]);
                                disposition.ModificationDate = System.IO.File.GetLastWriteTime(file[n]);
                                disposition.ReadDate = System.IO.File.GetLastAccessTime(file[n]);
                                //加入邮件附件
                                message.Attachments.Add(data);
                            }
                        }
                    }
                    message.Body = dt.Rows[i]["html_text"].ToString();
                    message.IsBodyHtml = true;
                    message.BodyEncoding = Encoding.UTF8;

                    try
                    {
                        //再次检查一下数据库，如果邮件是已经发送或者失败5次以上则停止发送，解决多线程并发处理时邮件重复发送的问题
                        string sqlCheck = "select * from dbo.COM_SendMail where mail_id = '" + dt.Rows[i]["mail_id"].ToString() + "' and is_send='N' and retry_times < 5";
                        DataTable dtCheck = sql.ExecuteDataset(sqlCheck).Tables[0];

                        if (dtCheck != null && dtCheck.Rows.Count > 0)
                        {
                            client.Send(message);

                            string strupdatemail = "UPDATE [dbo].[COM_SendMail] SET  is_send='Y',send_time=@send_time where mail_id=@mail_id";
                            SqlParameter[] parameters = {
					            new SqlParameter("@send_time", SqlDbType.DateTime),
                                new SqlParameter("@mail_id", SqlDbType.NVarChar,50)
                                               };
                            parameters[0].Value = System.DateTime.Now;
                            parameters[1].Value = dt.Rows[i]["mail_id"].ToString();
                            sql.ExecuteNonQuery(strupdatemail, parameters);
                        }
                    }
                    catch (Exception e)
                    {
                        _log.Error("邮件发送出现异常" + e.ToString() + "发生异常的邮件ID为：" + dt.Rows[i]["mail_id"].ToString());
                    }
                    finally
                    {
                        message.To.Clear();
                        message.CC.Clear();
                        message.Attachments.Clear();

                        string strupdateretry = "UPDATE [dbo].[COM_SendMail] SET  retry_times=retry_times + 1 where mail_id=@mail_id";
                        SqlParameter[] parameterstry ={
                                new SqlParameter("@mail_id", SqlDbType.NVarChar,50)
                                                };
                        parameterstry[0].Value = dt.Rows[i]["mail_id"].ToString();
                        sql.ExecuteNonQuery(strupdateretry, parameterstry);
                    }
                    
                }
            }
            catch (Exception e)
            {
                _log.Fatal("邮件发送出现异常，异常信息：" + e.ToString());
            }

            _log.Info("发送邮件结束");
            _log.Info("----------------------------End--------------------------------");
        }

        public void Dispose()
        {
        }
        #endregion

        #region IServiceStrategy 成员

        public void Do()
        {
            SendMail();
        }

        #endregion
    }
}
